package com.kaesun.ufit.treadmill;

import android.app.Application;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;

import com.kaesun.ufit.hardware.CardioController;
import com.kaesun.ufit.hardware.Ds1307;
import com.kaesun.ufit.hardware.Ds1307.RtcDate;
import com.kaesun.ufit.hardware.Ds1307.RtcTime;
import com.kaesun.ufit.hardware.RfidReader;
import com.kaesun.ufit.hardware.WiFi;
import com.kaesun.ufit.tools.ConfigData;
import com.kaesun.ufit.tools.ExcerciseData;

public class MainApplication extends Application implements IOnHandlerMessage {
	/*private static final String TAG = "MainApplication";
	private void log(String log) {
		Log.i(TAG, log);
	}*/

	public static final String PROGRAM_VERSION = "0.93 beta";

	public static final int HANDLER_RX_RFIDREADER = 1000;
	public static final int HANDLER_RX_WIFI = 1001;
	public static final int HANDLER_RX_CARDIOCONTROLLER = 1002;

	public static final int HANDLER_TIMEOUT_SECOND = 2000;
	public static final int HANDLER_TIMEOUT_ACTIVITY = 2001;

	private static final int HANDLER_UPDATE_RTC = 1;
	private static final int INTERVAL_UPDATE_RTC = 1000;

	private static final int TIMEROUT_ACTIVITY = 60000;	// [msec]

	private RfidReader mRfidReader = new RfidReader();
	private WiFi mWiFi = new WiFi();
	private CardioController mCardioController = new CardioController();
	private Ds1307 mRtc = new Ds1307();

	private WeakRefHandler mHandlerRtc = null;
	private WeakRefHandler mHandlerActivity = null;
	private long mTimeoutActivity = 0;

	private WakeLock mWakeLock = null;
	
	
	public ExcerciseData mExcerciseData = new ExcerciseData();


	@SuppressWarnings("deprecation")
	@Override
	public void onCreate() {
		super.onCreate();

		mRfidReader.start();
		mWiFi.start();
		mCardioController.start();
		mRtc.update();

		mHandlerRtc = new WeakRefHandler((IOnHandlerMessage)this);
		mHandlerRtc.sendEmptyMessageDelayed(HANDLER_UPDATE_RTC, INTERVAL_UPDATE_RTC);

		mWakeLock = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.FULL_WAKE_LOCK, "WakeAlways");
		mWakeLock.acquire();
	}

	@Override
	public void onTerminate() {
		stopHardware();
		mWakeLock.release();

		super.onTerminate();
	}


	public void stopHardware() {
		mCardioController.stop();
		mWiFi.stop();
		mRfidReader.stop();
	}

	public void setHandler(WeakRefHandler handler, boolean timeout) {
		mRfidReader.setHandler(handler);
		mWiFi.setHandler(handler);
		mCardioController.setHandler(handler);

		mHandlerActivity = handler;
		if (timeout) {
			mTimeoutActivity = mRtc.getTimeInMillis();
		} else {
			mTimeoutActivity = 0;
		}
	}

	public void timeoutReset() {
		mTimeoutActivity = mRtc.getTimeInMillis();
	}


	public void wiFiAssociation() {
		String ssid = ConfigData.getPrefString(this, ConfigData.PREF_WIFI_SSID, ConfigData.DEF_WIFI_SSID);;//"erionet3";//"smart-fit";//
		String security = ConfigData.getPrefString(this, ConfigData.PREF_WIFI_SECURITY, ConfigData.DEF_WIFI_SECURITY);//"WPA2";
		String password = ConfigData.getPrefString(this, ConfigData.PREF_WIFI_PASSWORD, ConfigData.DEF_WIFI_PASSWORD);//"erionet7";//"kaesun1811";

		String server = ConfigData.getPrefString(this, ConfigData.PREF_WIFI_SERVER, ConfigData.DEF_WIFI_SERVER);//"192.168.0.48";
		int port = ConfigData.getPrefInteger(this, ConfigData.PREF_WIFI_PORT, ConfigData.DEF_WIFI_PORT);//9001;

		mWiFi.association(ssid, security, password, server, port);
	}

	public boolean wiFiSendTag(String userId) {
		String request = "command=w11";
		request += String.format("&ip=%s", mWiFi.mIpAddress);
		request += String.format("&neoid=%s", ConfigData.getPrefString(this, ConfigData.PREF_MODEL_NEO_ID, ConfigData.DEF_MODEL_NEO_ID));
		request += String.format("&userid=%s", userId);

		return mWiFi.sendRequest(request);
	}

	public boolean wiFiSendExcercise() {
		String request = "command=w12";
		request += String.format("&ip=%s", mWiFi.mIpAddress);
		request += String.format("&hashcode=%s", mExcerciseData.mHashCode);
		request += String.format("&neoid=%s", mExcerciseData.mNeoId);
		request += String.format("&userid=%s", mExcerciseData.mUserId);
		request += String.format("&weight=%f", mExcerciseData.mMeasureWeight);
		request += String.format("&distance=%f", mExcerciseData.mMeasureDistance);
		request += String.format("&count=%d", mExcerciseData.mMeasureCount);
		request += String.format("&time=%d", mExcerciseData.mMeasureTime);
		request += String.format("&set=%d", mExcerciseData.mMeasureSet);
		request += String.format("&calories=%f", mExcerciseData.mMeasureCalories);
		request += String.format("&rate=%f", mExcerciseData.mMeasureRate);
		for (int i=0; i<mExcerciseData.mMeasureSetCount.length; i++) {
			if (0 < mExcerciseData.mMeasureSetCount[i]) {
				request += String.format("&set%dcnt=%d", i+1, mExcerciseData.mMeasureSetCount[i]);
			}
		}

		return mWiFi.sendRequest(request);
	}

	public boolean wiFiSendMeasure() {
		String request = "command=w13";
		request += String.format("&ip=%s", mWiFi.mIpAddress);
		request += String.format("&hashcode=%s", mExcerciseData.mHashCode);
		request += String.format("&neoid=%s", mExcerciseData.mNeoId);
		request += String.format("&userid=%s", mExcerciseData.mUserId);
		request += String.format("&weight=%f", mExcerciseData.mMeasureWeight);
		request += String.format("&distance=%f", mExcerciseData.mMeasureDistance);
		request += String.format("&count=%d", mExcerciseData.mMeasureCount);
		request += String.format("&time=%d", mExcerciseData.mMeasureTime);
		request += String.format("&set=%d", mExcerciseData.mMeasureSet);
		request += String.format("&calories=%f", mExcerciseData.mMeasureCalories);

		return mWiFi.sendRequest(request);
	}

	public boolean wiFiSendFreeExcercise() {
		String request = "command=w14";
		request += String.format("&ip=%s", mWiFi.mIpAddress);
		request += String.format("&neoid=%s", ConfigData.getPrefString(this, ConfigData.PREF_MODEL_NEO_ID, ConfigData.DEF_MODEL_NEO_ID));
		request += String.format("&weight=%f", mExcerciseData.mMeasureWeight);
		request += String.format("&distance=%f", mExcerciseData.mMeasureDistance);
		request += String.format("&count=%d", mExcerciseData.mMeasureCount);
		request += String.format("&time=%d", mExcerciseData.mMeasureTime);
		request += String.format("&set=%d", mExcerciseData.mMeasureSet);
		request += String.format("&calories=%f", mExcerciseData.mMeasureCalories);
		for (int i=0; i<mExcerciseData.mMeasureSetCount.length; i++) {
			if (0 < mExcerciseData.mMeasureSetCount[i]) {
				request += String.format("&set%dcnt=%d", i+1, mExcerciseData.mMeasureSetCount[i]);
			}
		}

		return mWiFi.sendRequest(request);
	}
	

	public String cardioController(int cmd, int n) {
		return mCardioController.send(cmd, n);
	}


	public void rtcSetDate(int year, int month, int date) {
		mRtc.setRtcDate(year, month, date);
	}

	public RtcDate rtcDate() {
		return mRtc.rtcDate();
	}

	public void rtcSetTime(int hour, int minute, int second) {
		mRtc.setRtcTime(hour, minute, second);
	}

	public RtcTime rtcTime() {
		return mRtc.rtcTime();
	}

	public long rtcGetTimeInMillis() {
		return mRtc.getTimeInMillis();
	}


	private int mLastSecond = -1;
	@Override
	public void handleMessage(Message msg) {
		if (HANDLER_UPDATE_RTC == msg.what) {
			if (-1 == mLastSecond) {
				wiFiAssociation();
			}

			RtcTime rtcTime = mRtc.update();
			if (mLastSecond != rtcTime.mSecond) {
				mLastSecond = rtcTime.mSecond;

				if (null != mHandlerActivity) {
					mHandlerActivity.sendMessage(mHandlerActivity.obtainMessage(HANDLER_TIMEOUT_SECOND, rtcTime.mHour, rtcTime.mMinute));
				}
			}

			if (0 < mTimeoutActivity) {
				long elapsed = mRtc.getTimeInMillis() - mTimeoutActivity;
				if (TIMEROUT_ACTIVITY < elapsed) {
					if (null != mHandlerActivity) {
						mTimeoutActivity = 0;
						mHandlerActivity.sendEmptyMessage(HANDLER_TIMEOUT_ACTIVITY);
					}
				}
			}

			mHandlerRtc.sendEmptyMessageDelayed(HANDLER_UPDATE_RTC, INTERVAL_UPDATE_RTC);
		}
	}
}
